function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function robustSleep(ms) {
  const end = Date.now() + ms;
  while (Date.now() < end) {
    const remaining = end - Date.now();
    await new Promise((resolve) => setTimeout(resolve, Math.min(100, remaining)));
  }
}

function calculateLuhnCheckDigit(numberWithoutCheckDigit) {
  let sum = 0;
  let doubleDigit = true;

  for (let index = numberWithoutCheckDigit.length - 1; index >= 0; index -= 1) {
    let digit = parseInt(numberWithoutCheckDigit[index], 10);
    if (doubleDigit) {
      digit *= 2;
      if (digit > 9) {
        digit -= 9;
      }
    }
    sum += digit;
    doubleDigit = !doubleDigit;
  }

  const checkDigit = (10 - (sum % 10)) % 10;
  return checkDigit.toString();
}

function isValidLuhn(cardNumber) {
  let sum = 0;
  let doubleDigit = false;

  for (let index = cardNumber.length - 1; index >= 0; index -= 1) {
    let digit = parseInt(cardNumber[index], 10);
    if (doubleDigit) {
      digit *= 2;
      if (digit > 9) {
        digit -= 9;
      }
    }
    sum += digit;
    doubleDigit = !doubleDigit;
  }

  return sum % 10 === 0;
}

function calculateCheckDigit(sequence) {
  return calculateLuhnCheckDigit(sequence);
}

function isValidCardNumber(number) {
  return isValidLuhn(number);
}

const MII_DEFINITIONS = {
  0: 'ISO/TC 68 and other industry assignments',
  1: 'Airlines',
  2: 'Airlines and other future industry assignments',
  3: 'Travel and Entertainment (American Express, Diners Club, JCB, etc.)',
  4: 'Banking and Financial (Visa)',
  5: 'Banking and Financial (MasterCard)',
  6: 'Merchandising and Banking/Financial (Discover, UnionPay)',
  7: 'Petroleum and other future industry assignments',
  8: 'Healthcare, Telecommunications and future industry assignments',
  9: 'National assignment',
};

const VALID_BIN_RANGES = {
  Visa: [{ start: '4', length: 1 }],
  MasterCard: [
    { start: '51', end: '55' },
    { start: '2221', end: '2720' },
  ],
  'American Express': [
    { start: '34', length: 2 },
    { start: '37', length: 2 },
  ],
  'Diners Club': [
    { start: '36', length: 2 },
    { start: '38', length: 2 },
    { start: '300', end: '305' },
    { start: '309', length: 3 },
  ],
  Discover: [
    { start: '6011', length: 4 },
    { start: '622126', end: '622925' },
    { start: '644', end: '649' },
    { start: '65', length: 2 },
  ],
  JCB: [{ start: '3528', end: '3589' }],
  UnionPay: [{ start: '62', length: 2 }],
};

function validateBinFormat(bin) {
  const normalized = bin.toString().trim();

  if (!normalized || normalized.length < 4) {
    return { valid: false, error: 'BIN长度至少需要4位数字', code: 'BIN_TOO_SHORT' };
  }

  if (normalized.length > 10) {
    return { valid: false, error: 'BIN长度不应超过10位数字', code: 'BIN_TOO_LONG' };
  }

  if (!/^\d+$/.test(normalized)) {
    return { valid: false, error: 'BIN只能包含数字', code: 'BIN_INVALID_CHARS' };
  }

  const mii = normalized[0];
  if (!MII_DEFINITIONS[mii]) {
    return {
      valid: false,
      error: `无效的主要行业标识符（MII）：${mii}`,
      code: 'INVALID_MII',
    };
  }

  if (!['3', '4', '5', '6'].includes(mii)) {
    return {
      valid: false,
      error: `MII ${mii} 不属于银行金融类别，应该是3、4、5或6开头`,
      code: 'NON_BANKING_MII',
      miiType: MII_DEFINITIONS[mii],
    };
  }

  return {
    valid: true,
    mii,
    miiType: MII_DEFINITIONS[mii],
    binLength: normalized.length,
  };
}

function validateBinRange(bin) {
  const normalized = bin.toString();
  const matchedBrands = [];

  for (const [brand, ranges] of Object.entries(VALID_BIN_RANGES)) {
    for (const range of ranges) {
      if (range.length) {
        if (normalized.startsWith(range.start)) {
          matchedBrands.push(brand);
          break;
        }
      } else if (range.end) {
        const sample = normalized.substring(0, range.start.length);
        const start = parseInt(range.start, 10);
        const end = parseInt(range.end, 10);
        const value = parseInt(sample, 10);
        if (value >= start && value <= end) {
          matchedBrands.push(brand);
          break;
        }
      }
    }
  }

  if (matchedBrands.length > 0) {
    return { valid: true, matchedBrands, primaryBrand: matchedBrands[0] };
  }

  return {
    valid: false,
    error: 'BIN不匹配任何已知的银行卡品牌范围',
    code: 'UNKNOWN_BIN_RANGE',
  };
}

function validateBin(bin) {
  const normalized = bin.toString().trim();
  console.log(`\n🔍 开始校验BIN: ${normalized}`);

  const formatResult = validateBinFormat(normalized);
  if (!formatResult.valid) {
    console.error(`❌ BIN格式校验失败: ${formatResult.error}`);
    return formatResult;
  }

  console.log('✅ BIN格式校验通过');
  console.log(`   - MII: ${formatResult.mii} (${formatResult.miiType})`);
  console.log(`   - BIN长度: ${formatResult.binLength}位`);

  const rangeResult = validateBinRange(normalized);
  if (!rangeResult.valid) {
    console.warn(`⚠️ BIN范围校验失败: ${rangeResult.error}`);
    console.warn('   该BIN可能不是常见银行卡品牌，但仍可尝试生成');
    return {
      valid: true,
      warning: rangeResult.error,
      mii: formatResult.mii,
      miiType: formatResult.miiType,
      isUnknownBrand: true,
    };
  }

  console.log('✅ BIN范围校验通过');
  console.log(`   - 匹配品牌: ${rangeResult.matchedBrands.join(', ')}`);
  console.log(`   - 主要品牌: ${rangeResult.primaryBrand}`);

  return {
    valid: true,
    mii: formatResult.mii,
    miiType: formatResult.miiType,
    binLength: formatResult.binLength,
    matchedBrands: rangeResult.matchedBrands,
    primaryBrand: rangeResult.primaryBrand,
  };
}

function detectCardBrand(bin) {
  const normalized = bin.toString();

  if (normalized.startsWith('4')) {
    return { name: 'Visa', length: 16, cvvLength: 3 };
  }

  if (/^5[1-5]/.test(normalized)) {
    return { name: 'MasterCard', length: 16, cvvLength: 3 };
  }

  if (normalized.startsWith('2') && normalized.length >= 4) {
    const prefix = parseInt(normalized.slice(0, 4), 10);
    if (prefix >= 2221 && prefix <= 2720) {
      return { name: 'MasterCard', length: 16, cvvLength: 3 };
    }
  }

  if (normalized.startsWith('34') || normalized.startsWith('37')) {
    return { name: 'American Express', length: 15, cvvLength: 4 };
  }

  if (normalized.startsWith('62')) {
    return { name: 'UnionPay', length: 16, cvvLength: 3 };
  }

  if (
    normalized.startsWith('6011') ||
    /^64[4-9]/.test(normalized) ||
    normalized.startsWith('65')
  ) {
    return { name: 'Discover', length: 16, cvvLength: 3 };
  }

  if (normalized.startsWith('36') || normalized.startsWith('38')) {
    return { name: 'Diners Club', length: 14, cvvLength: 3 };
  }

  if (/^35[2-8]/.test(normalized)) {
    return { name: 'JCB', length: 16, cvvLength: 3 };
  }

  return { name: 'Unknown', length: 16, cvvLength: 3 };
}

function getRealisticRandomDigit() {
  const distribution = [0.09, 0.1, 0.11, 0.1, 0.1, 0.11, 0.1, 0.09, 0.1, 0.1];
  const random = Math.random();
  let cumulative = 0;

  for (let index = 0; index < distribution.length; index += 1) {
    cumulative += distribution[index];
    if (random < cumulative) {
      return index;
    }
  }

  return 5;
}

function generateBankStandardAccountSegment(position, currentNumber, expectedLength) {
  const distributions = {
    0: [0.05, 0.15, 0.15, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05],
    1: [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1],
    default: [0.08, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.04],
  };

  const weights = distributions[position] || distributions.default;
  const sample = Math.random();
  let cumulative = 0;

  for (let index = 0; index < weights.length; index += 1) {
    cumulative += weights[index];
    if (sample < cumulative) {
      return index.toString();
    }
  }

  return '5';
}

function weightedRandom(weights) {
  const total = weights.reduce((acc, weight) => acc + weight, 0);
  const target = Math.random() * total;
  let cumulative = 0;

  for (let index = 0; index < weights.length; index += 1) {
    cumulative += weights[index];
    if (target < cumulative) {
      return index;
    }
  }

  return weights.length - 1;
}

function generateAdvancedAccountSegment(length, binPrefix) {
  for (let attempt = 0; attempt < 100; attempt += 1) {
    let segment = '';
    const binTail = parseInt(binPrefix.slice(-4), 10) % 1000;
    const basePair = String(Math.floor(binTail / 10) % 100).padStart(2, '0');
    const patternWeights = [0.7, 0.2, 0.1];
    const mode = weightedRandom(patternWeights);

    if (length >= 2) {
      const randomShift = Math.floor(Math.random() * 10);
      segment += String((parseInt(basePair[0], 10) + randomShift) % 10);
      segment += String((parseInt(basePair[1], 10) + Math.floor(Math.random() * 3)) % 10);
    }

    const remaining = length - segment.length;
    for (let index = 0; index < remaining; index += 1) {
      const currentIndex = segment.length;
      if (mode === 0) {
        segment += generateBankStandardAccountSegment(currentIndex, segment, length);
      } else if (mode === 1) {
        if (currentIndex === 2) {
          segment += weightedRandom([0.1, 0.1, 0.3, 0.3, 0.1, 0.05, 0.05, 0, 0, 0]);
        } else {
          segment += generateBankStandardAccountSegment(currentIndex, segment, length);
        }
      } else if (currentIndex < 4) {
        segment += String(Math.floor(Math.random() * 10));
      } else {
        segment += generateBankStandardAccountSegment(currentIndex, segment, length);
      }
    }

    return segment;
  }

  let fallback = '';
  for (let index = 0; index < length; index += 1) {
    fallback += generateBankStandardAccountSegment(index, fallback, length);
  }
  return fallback;
}

function generateRealisticExpiryDate() {
  const now = new Date();
  const year = now.getFullYear();
  const currentMonth = now.getMonth() + 1;
  const offset = Math.floor(Math.random() * 3) + 3;
  let expiryYear = year + offset;
  let expiryMonth;

  if (Math.random() < 0.7) {
    const quarterMonths = [3, 6, 9, 12];
    expiryMonth = quarterMonths[Math.floor(Math.random() * quarterMonths.length)];
  } else {
    expiryMonth = Math.floor(Math.random() * 12) + 1;
  }

  if (expiryYear === year && expiryMonth <= currentMonth) {
    expiryYear += 1;
  }

  return {
    expMonth: String(expiryMonth).padStart(2, '0'),
    expYear: String(expiryYear).slice(-2),
  };
}

function generateCVV(binPrefix, isAmex, cvvLength = 3) {
  if (isAmex || cvvLength === 4) {
    return String(Math.floor(Math.random() * 0x2328) + 0x3e8);
  }

  let value;
  do {
    value = Math.floor(Math.random() * 0x384) + 0x64; // between 100 and 999
    const text = String(value);
    if (text[0] !== text[1] || text[1] !== text[2]) {
      break;
    }
  } while (true);

  return String(value);
}

function formatCardNumber(number, isAmex) {
  if (isAmex) {
    return number.replace(/(\d{4})(\d{6})(\d{5})/, '$1 $2 $3');
  }
  return number.replace(/(\d{4})(?=\d)/g, '$1 ');
}

function generateCardInfo(binPrefix) {
  if (!binPrefix || binPrefix.length === 0) {
    throw new Error('必须提供BIN前缀');
  }

  const normalizedBin = binPrefix.toString().replace(/\D/g, '');
  const validation = validateBin(normalizedBin);

  if (!validation.valid) {
    throw new Error(`BIN校验失败: ${validation.error} (错误码: ${validation.code})`);
  }

  if (validation.warning) {
    console.warn(`⚠️ BIN校验警告: ${validation.warning}`);
  }

  const brand = detectCardBrand(normalizedBin);
  const targetLength = brand.length;
  const isAmex = brand.name === 'American Express';
  const digitsToGenerate = targetLength - normalizedBin.length;

  if (digitsToGenerate <= 1) {
    throw new Error(`BIN长度过长，无法生成${targetLength}位卡号`);
  }

  let attempts = 0;
  const maxAttempts = 50;

  while (attempts < maxAttempts) {
    try {
      const accountSegmentLength = digitsToGenerate - 1;
      let accountNumber = normalizedBin;

      if (accountSegmentLength > 0) {
        accountNumber += generateAdvancedAccountSegment(accountSegmentLength, normalizedBin);
      }

      const checkDigit = calculateCheckDigit(accountNumber);
      const fullNumber = accountNumber + checkDigit;

      if (fullNumber.length !== targetLength) {
        console.error(
          `❌ 卡号长度错误: 期望${targetLength}位，实际${fullNumber.length}位`,
          fullNumber,
        );
        throw new Error(`生成的卡号长度不正确: 期望${targetLength}位，实际${fullNumber.length}位`);
      }

      if (!isValidCardNumber(fullNumber)) {
        console.warn('生成的卡号未通过Luhn校验:', fullNumber);
        attempts += 1;
        continue;
      }

      const { expMonth, expYear } = generateRealisticExpiryDate();
      const cvv = generateCVV(normalizedBin, isAmex, brand.cvvLength);

      return {
        cardNumber: formatCardNumber(fullNumber, isAmex),
        expiryDate: `${expMonth}/${expYear}`,
        cvc: cvv,
        cardBrand: brand.name,
      };
    } catch (error) {
      console.error(`生成卡号尝试 ${attempts + 1} 失败:`, error.message);
      attempts += 1;
    }
  }

  throw new Error('无法生成符合要求的高质量卡号，请尝试更换BIN或稍后重试');
}

async function getCheckoutUrl(tier = 'pro') {
  console.log('💳 获取绑卡页面URL...');

  const headers = {
    Accept: '*/*',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Content-Type': 'application/json',
    Origin: 'https://cursor.com',
    Priority: 'u=1, i',
    Referer: 'https://cursor.com/dashboard',
    'Sec-Ch-Ua-Arch': '"x86"',
    'Sec-Ch-Ua-Bitness': '"64"',
    'Sec-Ch-Ua-Mobile': '?0',
    'Sec-Ch-Ua-Platform': '"Windows"',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'User-Agent': navigator.userAgent,
  };

  const payload = {
    allowAutomaticPayment: true,
    allowTrial: true,
    tier,
  };

  try {
    console.log('📡 发送POST请求到: https://cursor.com/api/checkout');
    console.log('📦 请求数据:', payload);

    const response = await fetch('https://cursor.com/api/checkout', {
      method: 'POST',
      headers,
      body: JSON.stringify(payload),
      credentials: 'include',
    });

    console.log(`🔍 绑卡响应状态: ${response.status}`);

    if (response.status === 200) {
      try {
        const url = await response.json();
        console.log('✅ 绑卡页面请求成功!');
        console.log(`🔗 绑卡页面URL: ${url}`);

        if (url && url.includes('checkout.stripe.com')) {
          console.log('✅ 检测到Stripe支付页面');
          return { success: true, url };
        }

        console.warn('⚠️ 返回的URL不是预期的Stripe支付页面');
        return { success: false, url: null, error: 'Invalid checkout URL' };
      } catch (error) {
        const text = await response.text();
        console.error(`⚠️ 响应解析失败: ${text.substring(0, 200)}...`);
        return { success: false, url: null, error: 'Response parse error' };
      }
    }

    const errorText = await response.text();
    console.error(`❌ 绑卡页面请求失败: ${response.status}`);
    console.error(`📄 错误响应: ${errorText.substring(0, 200)}...`);
    return {
      success: false,
      url: null,
      error: `HTTP ${response.status}: ${errorText.substring(0, 100)}`,
    };
  } catch (error) {
    console.error(`❌ 绑卡请求异常: ${error.message}`);
    return { success: false, url: null, error: error.message };
  }
}
